package cn.iocoder.yudao.module.def.service.equipmentinfo;

import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.def.controller.admin.equipmentinfo.vo.EquipmentInfoPageReqVO;
import cn.iocoder.yudao.module.def.controller.admin.equipmentinfo.vo.EquipmentInfoRespVO;
import cn.iocoder.yudao.module.def.controller.admin.equipmentinfo.vo.EquipmentInfoSaveReqVO;
import cn.iocoder.yudao.module.def.dal.dataobject.equipmentinfo.EquipmentInfoDO;
import cn.iocoder.yudao.module.def.dal.mysql.equipmentinfo.EquipmentInfoMapper;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.def.enums.ErrorCodeConstants.EQUIPMENT_INFO_NOT_EXISTS;

/**
 * 设备信息 Service 实现类
 *
 * @author 系统内置账号23
 */
@Service
@Validated
public class EquipmentInfoServiceImpl implements EquipmentInfoService {

    @Resource
    private EquipmentInfoMapper equipmentInfoMapper;

    @Override
    public Long createEquipmentInfo(EquipmentInfoSaveReqVO createReqVO) {
        // 插入
        EquipmentInfoDO equipmentInfo = BeanUtils.toBean(createReqVO, EquipmentInfoDO.class);
        equipmentInfoMapper.insert(equipmentInfo);
        // 返回
        return equipmentInfo.getId();
    }

    @Override
    public void updateEquipmentInfo(EquipmentInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateEquipmentInfoExists(updateReqVO.getId());
        // 更新
        EquipmentInfoDO updateObj = BeanUtils.toBean(updateReqVO, EquipmentInfoDO.class);
        equipmentInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteEquipmentInfo(Long id) {
        // 校验存在
        validateEquipmentInfoExists(id);
        // 删除
        equipmentInfoMapper.deleteById(id);
    }

    private void validateEquipmentInfoExists(Long id) {
        if (equipmentInfoMapper.selectById(id) == null) {
            throw exception(EQUIPMENT_INFO_NOT_EXISTS);
        }
    }

    @Override
    public EquipmentInfoDO getEquipmentInfo(Long id) {
        return equipmentInfoMapper.selectById(id);
    }

    @Override
    public PageResult<EquipmentInfoDO> getEquipmentInfoPage(EquipmentInfoPageReqVO pageReqVO) {
        return equipmentInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public void dealImportFile(MultipartFile file) throws IOException {
        try (InputStream inputStream = file.getInputStream()) {
            List<EquipmentInfoRespVO> list = readAllSheetsWithTypeName(inputStream);
            equipmentInfoMapper.insertBatch(BeanUtil.copyToList(list, EquipmentInfoDO.class));
        }
    }

    public List<EquipmentInfoRespVO> readAllSheetsWithTypeName(InputStream inputStream) {
        List<EquipmentInfoRespVO> allData = new ArrayList<>();

        ExcelReader excelReader = null;
        try {

            excelReader = EasyExcel.read(inputStream).build();

            List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();

            for (ReadSheet sheet : sheets) {
                String sheetName = sheet.getSheetName();
                Integer type = getTypeBySheetName(sheetName);
                if (type == null) {
                    continue;
                }

                // 为每个 sheet 创建读取配置
                ReadSheet readSheet = EasyExcel.readSheet(sheet.getSheetNo())
                        .head(EquipmentInfoRespVO.class)
                        .registerReadListener(new AnalysisEventListener<EquipmentInfoRespVO>() {
                            @Override
                            public void invoke(EquipmentInfoRespVO data, AnalysisContext context) {
                                if (data != null) {
                                    data.setType(type);
                                    allData.add(data);
                                    // 调试输出
                                    System.out.println("读取到数据: " + data.getDeviceName() + ", " + data.getDeviceType());
                                } else {
                                    System.out.println("警告：读取到 null 数据");
                                }
                            }

                            @Override
                            public void doAfterAllAnalysed(AnalysisContext context) {
                                System.out.println("Sheet [" + sheetName + "] 读取完成，类型: " + type);
                            }

                            @Override
                            public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
                                System.out.println("Sheet [" + sheetName + "] 表头: " + headMap);
                            }

                            @Override
                            public void onException(Exception exception, AnalysisContext context) {
                                System.err.println("读取异常: " + exception.getMessage());
                                exception.printStackTrace();
                            }
                        })
                        .build();

                excelReader.read(readSheet);
            }
        } catch (Exception e) {
            throw new RuntimeException("读取Excel文件失败", e);
        } finally {
            if (excelReader != null) {
                excelReader.finish();
            }
        }

        return allData;
    }

    private Integer getTypeBySheetName(String sheetName) {
        switch (sheetName) {
            case "在建设备":
                return 1;
            case "拟建设备":
                return 2;
            case "已建设备":
                return 3;
            default:
                System.out.println("跳过未知 Sheet: " + sheetName);
                return null;
        }
    }


    @Override
    public void exportMultiSheetEquipment(HttpServletResponse response) throws IOException {
        // 设置响应头
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; " +
                URLEncoder.encode("设备信息.xlsx", "UTF-8"));
        // 构建 writer
        ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream(), EquipmentInfoRespVO.class);
        ExcelWriter excelWriter = writerBuilder.build();

        LambdaQueryWrapper<EquipmentInfoDO> wrapper = new LambdaQueryWrapper<>();
        List<EquipmentInfoDO> list = equipmentInfoMapper.selectList(wrapper);
        List<EquipmentInfoRespVO> list1 = BeanUtil.copyToList(list.stream().filter(item -> item.getType() == 1).collect(Collectors.toList()), EquipmentInfoRespVO.class);
        List<EquipmentInfoRespVO> list2 = BeanUtil.copyToList(list.stream().filter(item -> item.getType() == 2).collect(Collectors.toList()), EquipmentInfoRespVO.class);
        List<EquipmentInfoRespVO> list3 = BeanUtil.copyToList(list.stream().filter(item -> item.getType() == 3).collect(Collectors.toList()), EquipmentInfoRespVO.class);
        // 写入多个 sheet
        writeSheet(excelWriter, list1, "在建设备", 0);
        writeSheet(excelWriter, list2, "拟建设备", 1);
        writeSheet(excelWriter, list3, "已建设备", 2);
        excelWriter.finish(); // 必须调用 finish，否则文件不完整
    }

    @Override
    public List<Map<String, Object>> getEquipmentIndex(String[] projectCates, String keyword, String[] sydws, String[] jsqys, String[] jsdws, String startYear, String endYear, String[] jsqyArea) {
        return equipmentInfoMapper.getEquipmentIndex(projectCates, keyword, sydws, jsqys, jsdws, startYear, endYear, jsqyArea);
    }

    private void writeSheet(ExcelWriter excelWriter, List<EquipmentInfoRespVO> data, String sheetName, int sheetNo) {
        WriteSheet sheet = EasyExcel.writerSheet(sheetNo, sheetName)
//                .registerWriteHandler(new CustomCellWriteHandler()) // 可选：自定义样式
                .needHead(true).build();

        excelWriter.write(data, sheet);
    }


}